package com.example.lock;

import org.springframework.util.StringUtils;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * redis 连接池
 *
 * @author mingtian
 */
public class LockService {
    private static JedisPool pool = null;

    static {
        JedisPoolConfig config = new JedisPoolConfig();
        // 设置最大连接数
        config.setMaxTotal(200);
        // 设置最大空闲数
        config.setMaxIdle(8);
        // 设置最大等待时间
        config.setMaxWaitMillis(1000 * 100);
        // 在borrow一个jedis实例时，是否需要验证，若为true，则所有jedis实例均是可用的
        config.setTestOnBorrow(true);
        pool = new JedisPool(config, "192.168.124.29", 6379, 5000, "123456");
    }

    private RedisLock redisLock = new RedisLock(pool);

    /**
     * 演示 redis 实现分布式锁
     */
    public void locks() throws InterruptedException {
        //1.获取锁 设置了5s的超时时间，key 失效时间也为 5s
        String value = redisLock.getRedisLock(5000L, 5000L);
        if (StringUtils.isEmpty(value)) {
            System.out.println(Thread.currentThread().getName() + "获取锁失败");
            return;
        }
        System.out.println(Thread.currentThread().getName() + ",获取锁成功，锁的id：" + value + '\n' + "开始执行业务逻辑");

        //2.执行业务逻辑，如果执行业务逻辑时间大于锁的超时时间，解决方案：
        // 1.我们可以适当增加锁的超时时间
        // 2.根据自己的业务场景，设置锁的超时时间
        // 3.记录业务执行时间，在释放锁之前判断如果业务执行时间大于锁的超时时间，需要回滚业务数据(手动回滚)，以保证数据的正确性。

        Thread.sleep(10000);

        //3.释放锁
        redisLock.unRedisLock(value);
    }

}